import 'dart:async';
import 'dart:io';
import 'dart:ui';
import 'package:ideology/features/models/editor_tab.dart';

/// 文件监听管理器
///
/// 用于监控项目目录与打开文件的变更：
/// - **目录监听/轮询**：检测文件结构变化并刷新资源管理器
/// - **文件监听/轮询**：检测文件内容变更并刷新活动标签页
/// - 支持平台不支持 `watch` 的兜底策略（定时轮询）
/// - 提供统一的停止方法以释放资源
class FileWatcherManager {
  /// 创建文件监听管理器
  ///
  /// - [getProjectRootPath] 获取项目根路径
  /// - [onExplorerShouldRefresh] 当资源管理器需要刷新时触发
  /// - [onActiveTabContentUpdated] 当当前活动标签页内容更新时触发
  /// - [requestNotify] 当需要提示用户时触发
  FileWatcherManager({
    required String? Function() getProjectRootPath,
    required VoidCallback onExplorerShouldRefresh,
    required VoidCallback onActiveTabContentUpdated,
    required VoidCallback requestNotify,
  })  : _getProjectRootPath = getProjectRootPath,
        _onExplorerShouldRefresh = onExplorerShouldRefresh,
        _onActiveTabContentUpdated = onActiveTabContentUpdated,
        _requestNotify = requestNotify;

  final String? Function() _getProjectRootPath;
  final VoidCallback _onExplorerShouldRefresh;
  final VoidCallback _onActiveTabContentUpdated;
  final VoidCallback _requestNotify;

  // ===== 目录监听 =====
  StreamSubscription<FileSystemEvent>? _dirWatcher;
  Timer? _dirPollTimer;
  String _lastDirSignature = '';
  Timer? _refreshDebounce;

  // ===== 文件监听 + 轮询 + 签名 =====
  final Map<EditorTab, StreamSubscription<FileSystemEvent>> _fileWatchers = {};
  final Map<EditorTab, Timer> _filePollTimers = {};
  final Map<EditorTab, String> _fileSignatures = {};

  /// 开始监听指定目录 [dirPath] 的变更（递归）
  ///
  /// 变更会触发资源管理器刷新；若平台不支持，则需依赖轮询
  void startDirectoryWatch(String dirPath) {
    _dirWatcher?.cancel();
    try {
      _dirWatcher = Directory(dirPath)
          .watch(recursive: true)
          .listen((_) => _debouncedRefreshExplorer());
    } catch (_) {
      // 平台可能不支持 watch，交由轮询兜底
    }
  }

  /// 启动目录轮询，定期计算目录签名检测变更
  void startDirectoryPolling(String dirPath) {
    _dirPollTimer?.cancel();
    _computeDirSignature(dirPath).then((sig) => _lastDirSignature = sig);

    _dirPollTimer = Timer.periodic(const Duration(milliseconds: 1500), (_) async {
      final root = _getProjectRootPath();
      if (root == null) return;
      final sig = await _computeDirSignature(root);
      if (sig != _lastDirSignature) {
        _lastDirSignature = sig;
        _debouncedRefreshExplorer();
      }
    });
  }

  /// 计算目录签名（包含文件修改时间与大小、子目录）
  Future<String> _computeDirSignature(String dirPath) async {
    try {
      final dir = Directory(dirPath);
      if (!await dir.exists()) return '';
      final entries = <String>[];
      await for (final entity in dir.list(recursive: true, followLinks: false)) {
        if (entity is File) {
          final stat = await entity.stat();
          final relPath =
          entity.path.replaceFirst('$dirPath${Platform.pathSeparator}', '');
          entries.add(
              '$relPath@${stat.modified.millisecondsSinceEpoch}@${stat.size}');
        } else if (entity is Directory) {
          final relPath =
          entity.path.replaceFirst('$dirPath${Platform.pathSeparator}', '');
          entries.add('$relPath/');
        }
      }
      entries.sort();
      return entries.join('|');
    } catch (_) {
      return '';
    }
  }

  /// 防抖触发资源管理器刷新
  void _debouncedRefreshExplorer() {
    _refreshDebounce?.cancel();
    _refreshDebounce = Timer(const Duration(milliseconds: 300), () {
      _onExplorerShouldRefresh();
    });
  }

  // ===== 文件监听 =====

  /// 启动某个标签页 [tab] 的文件监听
  ///
  /// - 支持文件修改与删除事件
  /// - 删除触发资源管理器刷新
  /// - 修改触发内容同步与通知
  void startFileWatchersForTab(EditorTab tab) {
    if (tab.fullPath.isEmpty) return;
    try {
      final sub = File(tab.fullPath)
          .watch(events: FileSystemEvent.modify | FileSystemEvent.delete)
          .listen((event) async {
        if (event.type == FileSystemEvent.delete) {
          _debouncedRefreshExplorer();
          return;
        }
        try {
          final newContent = await File(tab.fullPath).readAsString();
          if (newContent != tab.text.value && !tab.dirty.value) {
            tab.text.value = newContent;
            tab.dirty.value = false;
            _fileSignatures[tab] = await _computeFileSignature(tab.fullPath);
            _onActiveTabContentUpdated();
            _requestNotify();
          }
        } catch (_) {
          // ignore read error
        }
      });
      _fileWatchers[tab] = sub;
    } catch (_) {
      // 平台可能不支持 watch
    }
  }

  /// 停止某个标签页 [tab] 的文件监听
  void stopFileWatchersForTab(EditorTab tab) {
    _fileWatchers[tab]?.cancel();
    _fileWatchers.remove(tab);
  }

  // ===== 文件轮询兜底 =====

  /// 启动某个标签页 [tab] 的文件轮询
  ///
  /// - 定期计算文件签名并检测变更
  /// - 若内容变化且标签页未被标记为 `dirty`，则同步文件内容
  Future<void> startFilePollingForTab(EditorTab tab, {bool immediate = false}) async {
    _fileSignatures[tab] = await _computeFileSignature(tab.fullPath);
    _filePollTimers[tab]?.cancel();
    _filePollTimers[tab] =
        Timer.periodic(const Duration(milliseconds: 1500), (_) async {
          try {
            final currentSig = await _computeFileSignature(tab.fullPath);
            final lastSig = _fileSignatures[tab];
            if (currentSig != lastSig) {
              _fileSignatures[tab] = currentSig;
              if (!tab.dirty.value) {
                final fresh = await File(tab.fullPath).readAsString();
                if (fresh != tab.text.value) {
                  tab.text.value = fresh;
                  tab.dirty.value = false;
                  _onActiveTabContentUpdated();
                  _requestNotify();
                }
              }
            }
          } catch (_) {
            // 文件可能被删或无法访问
          }
        });

    if (immediate) {
      try {
        final sig = await _computeFileSignature(tab.fullPath);
        _fileSignatures[tab] = sig;
      } catch (_) {}
    }
  }

  /// 停止某个标签页 [tab] 的文件轮询
  void stopFilePollingForTab(EditorTab tab) {
    _filePollTimers[tab]?.cancel();
    _filePollTimers.remove(tab);
    _fileSignatures.remove(tab);
  }

  /// 刷新某个标签页 [tab] 的文件签名
  Future<void> refreshSignatureFor(EditorTab tab) async {
    _fileSignatures[tab] = await _computeFileSignature(tab.fullPath);
  }

  /// 计算文件签名（修改时间 + 大小）
  Future<String> _computeFileSignature(String fullPath) async {
    final f = File(fullPath);
    if (!await f.exists()) return 'missing';
    final stat = await f.stat();
    return '${stat.modified.millisecondsSinceEpoch}@${stat.size}';
  }

  // ===== 全部停止（用于关闭项目/销毁） =====

  /// 停止所有目录与文件监听、轮询任务并清理签名缓存
  void stopAll() {
    _dirWatcher?.cancel();
    _dirPollTimer?.cancel();
    _refreshDebounce?.cancel();

    for (final t in _fileWatchers.keys.toList()) {
      _fileWatchers[t]?.cancel();
    }
    _fileWatchers.clear();

    for (final t in _filePollTimers.keys.toList()) {
      _filePollTimers[t]?.cancel();
    }
    _filePollTimers.clear();

    _fileSignatures.clear();
  }
}
